package com.ljy.my_study.java.juc.lock.stampedlock;

import java.util.concurrent.locks.StampedLock;

public class StampedLockTestMain {

    public static void main(String[] args) {
        Point p=new Point();
        Runnable runnable=()->{
            p.move(1,2);
        };
        new Thread(runnable).start();
        try {
            Thread.sleep(100L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(p.distanceFromOrigin());
        System.out.println(p.distanceFromOrigin());
    }

    static class Point{
        private double x,y;
        private final StampedLock lock=new StampedLock();

        public void move(double dX,double dY){
            long stamp=lock.writeLock();
            try{
                System.out.println("move start");
                x+=dX;
                y+=dY;
                try {
                    Thread.sleep(3000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("move start");
            }finally {
                lock.unlockWrite(stamp);
            }
        }

        public double distanceFromOrigin(){
            long stamp=lock.tryOptimisticRead();
            double currentX=x,currentY=y;
            if(!lock.validate(stamp)){
                System.out.println("stamp is not validate.");
                long stampNew=lock.readLock();
                try{
                    System.out.println("get read lock start.");
                    currentX=x;
                    currentY=y;
                    System.out.println("get read lock end.");
                }finally {
                    lock.unlockRead(stampNew);
                }
            }else{
                System.out.println("stamp is validate.");
            }
            return Math.sqrt(currentX*currentX+currentY+currentY);
        }
    }
}
